package zero.tech.games.pdk.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.stereotype.Service;

import zero.tech.core.data.Resp;
import zero.tech.core.work.WorkManager;
import zero.tech.games.common.BigCalSource;
import zero.tech.games.common.Code;
import zero.tech.games.common.RoleId;
import zero.tech.games.logic.common.Room;
import zero.tech.games.logic.common.RoomCache;
import zero.tech.games.logic.data.RoomStatus;
import zero.tech.games.logic.data.res.ResReconnet;
import zero.tech.games.logic.util.LogicUtil;
import zero.tech.games.logic.util.PckUtil;
import zero.tech.games.pdk.data.PdkConfig;
import zero.tech.games.pdk.data.PdkGameBase;
import zero.tech.games.pdk.data.PdkRoomCache;
import zero.tech.games.pdk.data.PdkSmallPanel;
import zero.tech.games.pdk.data.PdkTimer;
import zero.tech.games.pdk.data.consts.PDKCMD;
import zero.tech.games.pdk.data.consts.PdkMode;
import zero.tech.games.pdk.data.entity.Card;
import zero.tech.games.pdk.data.entity.PlayerData;
import zero.tech.games.pdk.data.entity.PlayerSmallCal;
import zero.tech.games.pdk.data.entity.SetcardsPanel;
import zero.tech.games.pdk.data.notify.NotifyGameStart;
import zero.tech.games.pdk.data.res.ResPdkHandCards;
import zero.tech.games.pdk.service.api.IPdkService;
import zero.tech.games.pdk.util.CardUtil;
import zero.tech.games.pdk.util.PackageUtil;
import zero.tech.games.pdk.util.PlaybackUtil;
import zero.tech.games.pdk.util.RoomUtil;
import zero.tech.games.pdk.work.sync.GameOverCalculateSyncWork;
import zero.tech.wsnet.controller.LogicController;
import zero.tech.wsnet.data.Message;

@Service
public class PdkServiceImpl implements IPdkService{
	@Override
	public ResReconnet roomReconnect(Room room, LogicController online) {
		ResReconnet resReconnet=PackageUtil.packageResPdkReconnect(room,online);
		return resReconnet;
	}
	
	@Override
	public void roomTimer(Room room) {
		int room_status=room.getRoom_status();
		if(room_status==RoomStatus.DEFAULT) {
			RoomUtil.checkGameStart(room);
		}else if(room_status==RoomStatus.GAMING) {
			RoomUtil.autoOperate(room);
		}else if(room_status==RoomStatus.WAIT_NEXT_ROUND){
			RoomUtil.checkGameStart(room);
		}else if(room_status==RoomStatus.CALCULATING) {
			
		}
	}

	@Override
	public void gameStart(Room room) {
		initRoomBasic(room);
		initHandCards(room);
		initSmallPanel(room);
		initDispatchPos(room);
		notifyGameStart(room);
	}
	
	private void initSmallPanel(Room room) {
		PdkGameBase pdkGameBase = (PdkGameBase) room.getGameBase();
		PdkRoomCache pdkRoomCache = (PdkRoomCache) room.getRoomCache();
		int room_times=room.getRoom_times();
		String room_id=room.getRoom_id();
		String configStr=room.getConfigStr();
		PdkSmallPanel pdkSmallPanel = new PdkSmallPanel();
		pdkSmallPanel.setRoom_id(room_id);
		pdkSmallPanel.setConfigStr(configStr);		
		pdkSmallPanel.getDipai().addAll(pdkGameBase.getDipai());
		pdkRoomCache.getSmallPanels().put(room_times, pdkSmallPanel);
	}

	@Override
	public boolean checkGameOver(Room room, LogicController controller) {
		int uid=controller.getId();
		PdkGameBase pdkGameBase=(PdkGameBase) room.getGameBase();
		PlayerData playerData =pdkGameBase.getPlayers().get(uid);
		Map<Integer,Card> hands=playerData.getHands();
		return hands.isEmpty();
	}

	@Override
	public void gameOver(Room room, LogicController winner) {
		//小结算
		smallCalculate(room,winner);
	}
	

	@Override
	public void bigCalculate(Room room,int bigcalsource) {
		room.setRoom_status(RoomStatus.CALCULATING);
		WorkManager.getManager().submit(GameOverCalculateSyncWork.class,room,bigcalsource);
	}

	private void smallCalculate(Room room, LogicController winner) {
		int room_times=room.getRoom_times();
		PdkRoomCache pdkRoomCache = (PdkRoomCache) room.getRoomCache();
		PdkConfig pdkConfig = (PdkConfig) room.getGameConfig();
		pdkRoomCache.setPre_small_winner_uid(winner.getId());
		
		calculateSmallPanel(room);
		
		LogicUtil.broadRoomAllControllersInclude(room, Message.build(PDKCMD.NOTIFY_SMALL_CALCULATE, Resp.build(Code.OK, "小结算数据",PckUtil.packageNotifySmallCalculate(room))));
		
		//检查是否有玩家的钱不够进行下一轮
		boolean advance_big_calculate=false;
		for(LogicController logicController:room.getAllControllers().values()) {
			boolean ok=RoomUtil.checkMoneyEnoughNextRound(room, logicController);
			if(!ok) {
				advance_big_calculate=true;
				break;
			}
		}
		int total_times=pdkConfig.getTotal_times();
		if(advance_big_calculate||room_times>=total_times) {
			bigCalculate(room,BigCalSource.SMALLOVER_BIG_CAL);
		}else {
			smallCalculateReset(room);
		}
	}

	private void calculateSmallPanel(Room room) {
		int room_times=room.getRoom_times();
		PdkRoomCache pdkRoomCache = (PdkRoomCache) room.getRoomCache();
		int winner_uid=pdkRoomCache.getPre_small_winner_uid();
		PdkSmallPanel pdkSmallPanel = (PdkSmallPanel) pdkRoomCache.getSmallPanels().get(room_times);
		pdkSmallPanel.setHupai_uid(winner_uid);
		pdkSmallPanel.setGameOverTime(System.currentTimeMillis());
		List<PlayerSmallCal> playerCals=smallCalScoreBegin(room);
		pdkSmallPanel.getPlayerCals().addAll(playerCals);		
	}

	private List<PlayerSmallCal> smallCalScoreBegin(Room room) {
		PdkConfig pdkConfig = (PdkConfig) room.getGameConfig();
		PdkGameBase pdkGameBase = (PdkGameBase) room.getGameBase();
		Map<Integer,Integer> score_hands=scoreHand(room);
		Map<Integer,Integer> score_bombs=scoreBomb(room);
		
		long base_score=pdkConfig.getBase_score();
		Map<Integer,PlayerData> playerDatas=pdkGameBase.getPlayers();
		List<PlayerSmallCal> list=new ArrayList<>();
		//计算积分以及金币
		for(PlayerData playerData:playerDatas.values()) {
			int uid=playerData.getUid();
			int score_hand=score_hands.get(uid);
			int score_bomb=score_bombs.get(uid);
			int cur_win_score=0;
			if(pdkConfig.getWuzhadan()==1) {
				cur_win_score=score_hand;
			}else {
				cur_win_score=score_hand+score_bomb;
			}
			LogicController logicController = room.getAllControllers().get(uid);
			long cur_win_gold=cur_win_score*base_score;
			
			//计算玩家分数
			long old_win_gold=logicController.getWin();
			long old_gold=logicController.getGold();
			logicController.setWin(old_win_gold+cur_win_gold);
			logicController.setGold(old_gold+cur_win_gold);
			
			PlayerSmallCal playerSmallCal = new PlayerSmallCal();
			playerSmallCal.getHands().addAll(playerData.getHands().values());
			playerSmallCal.getOuts().addAll(playerData.getOuts());
			playerSmallCal.setZhadan_count(playerData.getZhadan_count());
			playerSmallCal.setCur_win_score(cur_win_score);
			playerSmallCal.setCur_win_gold(cur_win_gold);
			playerSmallCal.setScore_bomb(score_bomb);
			playerSmallCal.setScore_hand(score_hand);
			playerSmallCal.setTotal_win_gold(logicController.getWin());
			playerSmallCal.setLeft_gold(logicController.getGold());
			playerSmallCal.setSimpleUser(logicController.getSimpleUser());
			list.add(playerSmallCal);
		}
		
		
		return list;
	}
	

	private Map<Integer, Integer> scoreHand(Room room) {
		Map<Integer, Integer> score_hand=new HashMap<>();
		PdkGameBase pdkGameBase =(PdkGameBase) room.getGameBase();
		PdkRoomCache pdkRoomCache = (PdkRoomCache) room.getRoomCache();
		PdkConfig pdkConfig = (PdkConfig) room.getGameConfig();
		int winner_uid=pdkRoomCache.getPre_small_winner_uid();
		Map<Integer,PlayerData> playerDatas=pdkGameBase.getPlayers();
		int total_win_score=0;
		boolean hashongshi=pdkGameBase.isHashongshi();
		for(Entry<Integer,PlayerData> entry:playerDatas.entrySet()) {
			PlayerData playerData = entry.getValue();
			int uid=playerData.getUid();
			int left_cards=playerData.getHands().size();
			if(left_cards==1) {
				//报单不输钱
				left_cards=0;
			}
			int out_cards=playerData.getOuts().size();
			boolean spring=out_cards==0?true:false;
			if(uid!=winner_uid) {
				//输家
				int score=0;
				if(spring) {
					score+=-left_cards*2;
				}else {
					score+=-left_cards;
				}
				
				if(pdkConfig.getHongshi()==1&&hashongshi) {
					score-=5;
				}
				if(pdkConfig.getHongshi()==2&&hashongshi) {
					score*=2;
				}
				score_hand.put(uid, score);
				total_win_score+=-score;
			}
		}
		score_hand.put(winner_uid,total_win_score);
		return score_hand;
	}

	private Map<Integer, Integer> scoreBomb(Room room) {
		PdkGameBase pdkGameBase =(PdkGameBase) room.getGameBase();
		Map<Integer,PlayerData> playerDatas=pdkGameBase.getPlayers();
		Map<Integer,Integer> score_bomb =new HashMap<>();
		//计算炸弹得分
		for(Entry<Integer,PlayerData> entry:playerDatas.entrySet()) {
			int uid=entry.getKey();
			if(!score_bomb.containsKey(uid)) {
				score_bomb.put(uid, 0);
			}
			int zhadan_count=entry.getValue().getZhadan_count();
			if(zhadan_count>0) {
				scoreBomb(uid,zhadan_count,score_bomb,playerDatas);
			}
		}
		return score_bomb;
	}

	private void scoreBomb(int uid, int zhadan_count, Map<Integer, Integer> score_map, Map<Integer, PlayerData> playerDatas) {
		int total=0;
		for(Entry<Integer,PlayerData> playerData:playerDatas.entrySet()) {
			int other_uid=playerData.getKey();
			if(uid!=other_uid) {
				int lose_score=-zhadan_count*10;
				if(!score_map.containsKey(other_uid)) {
					score_map.put(other_uid, lose_score);
				}else {
					int old=score_map.get(other_uid);
					score_map.put(other_uid,old+lose_score);
				}
				total+=-lose_score;
			}
		}
		if(!score_map.containsKey(uid)) {
			score_map.put(uid, total);
		}else {
			int old=score_map.get(uid);
			score_map.put(uid, old+total);
		}
	}

	private void smallCalculateReset(Room room) {
		PlaybackUtil.saveClubSmallPlayback(room);//临时保存小局战绩数据
		room.setRoom_status(RoomStatus.WAIT_NEXT_ROUND);
		String room_id=room.getRoom_id();
		PdkGameBase pdkGameBase =new PdkGameBase(room_id);
		room.setGameBase(pdkGameBase);
		PdkTimer pdkTimer=new PdkTimer(room.getRoom_id());
		room.setTimer(pdkTimer);
		RoomCache roomCache = room.getRoomCache();
		roomCache.getWatchers().clear();//清除观战者
		LogicUtil.broadRoomAllControllersInclude(room, Message.build(PDKCMD.NOTIFY_SMALL_RESET, Resp.build(Code.OK, "小结算重置消息",PckUtil.packageNotifySmallReset(room))));
	}
	

	private void initRoomBasic(Room room) {
		PdkTimer pdkTimer=(PdkTimer) room.getTimer();
		room.setRoom_status(RoomStatus.GAMING);
		room.setRoom_times(room.getRoom_times()+1);
		pdkTimer.lastDispatchTime=System.currentTimeMillis();
	}

	private void initDispatchPos(Room room) {
		PdkGameBase pdkGameBase=(PdkGameBase) room.getGameBase();
		PdkRoomCache pdkRoomCache=(PdkRoomCache) room.getRoomCache();
		Integer pre_small_winner_uid=pdkRoomCache.getPre_small_winner_uid();
		if(pre_small_winner_uid==null) {
			//黑三先出
			PlayerData playerData=calculateHei3PlayerData(room,pdkGameBase);
			if(playerData==null) {
				//没有黑三,找牌最小的出
				List<PlayerData> list=new ArrayList<>();
				list.addAll(pdkGameBase.getPlayers().values());
				Collections.sort(list,new Comparator<PlayerData>() {

					@Override
					public int compare(PlayerData o1, PlayerData o2) {
						List<Card> cards1=new ArrayList<>();
						cards1.addAll(o1.getHands().values());
						Collections.sort(cards1,new Comparator<Card>() {

							@Override
							public int compare(Card o1, Card o2) {
								return o1.getCardNum()-o2.getCardNum();
							}
						});
						Card card_first1=cards1.get(0);
						
						
						List<Card> cards2=new ArrayList<>();
						cards2.addAll(o2.getHands().values());
						
						Collections.sort(cards2,new Comparator<Card>() {

							@Override
							public int compare(Card o1, Card o2) {
								return o1.getCardNum()-o2.getCardNum();
							}
						});
						Card card_sencond2=cards2.get(0);
						int result= card_first1.getCardNum()-card_sencond2.getCardNum();
						if(result!=0) {
							return result;
						}
						result=card_sencond2.getCardColor()-card_first1.getCardColor();
						return result;
					}
				});
				
				playerData=list.get(0);
			}
			pdkGameBase.setDispatch_uid(playerData.getUid());
		}else {
			//上局赢家先出
			pdkGameBase.setDispatch_uid(pre_small_winner_uid);
		}
	}

	private PlayerData calculateHei3PlayerData(Room room, PdkGameBase pdkGameBase) {
		PlayerData playerData=null;
		Map<Integer, PlayerData> playerDatas=pdkGameBase.getPlayers();
		for(PlayerData find:playerDatas.values()) {
			Map<Integer,Card> hands=find.getHands();
			if(hands.containsKey(RoomUtil.HEISANID)) {
				playerData=find;
				break;
			}
		}
		return playerData;
	}

	private void notifyGameStart(Room room) {
		for(LogicController logicController:room.getAllControllers().values()) {
			NotifyGameStart notifyGameStart=PackageUtil.packageNotifyGameStart(room,logicController);
			logicController.getWebClient().sendMessage(Message.build(PDKCMD.NOTIFY_GAME_START, Resp.build(Code.OK, "通知游戏开始",notifyGameStart)));
		}
	}

	private void initHandCards(Room room) {
		PdkRoomCache pdkRoomCache = (PdkRoomCache) room.getRoomCache();
		PdkGameBase pdkGameBase=(PdkGameBase) room.getGameBase();
		PdkConfig pdkConfig = (PdkConfig) room.getGameConfig();
		SetcardsPanel setcardsPanel = pdkRoomCache.getSetcardsPanel();
		Map<Integer, LogicController> controllers=room.getAllControllers();
		Map<Integer, List<Integer>> setsmap =setcardsPanel.getSetsmap();
		List<Card> deck=new ArrayList<>();
		List<Integer> uids=new ArrayList<>();
		uids.addAll(controllers.keySet());
		Collections.shuffle(uids);
		int length=16;
		if(!setsmap.isEmpty()) {
			//配牌器发牌
			List<Integer> setcard_uids=new ArrayList<>();
			if(pdkConfig.getPdk_mode()==PdkMode.MODE16) {
				deck.addAll(CardUtil.pdk16mode());
			}else if(pdkConfig.getPdk_mode()==PdkMode.MODE15) {
				deck.addAll(CardUtil.pdk15mode());
				length=15;
			}
			Collections.shuffle(deck);//洗牌
			for(Entry<Integer,List<Integer>> entry:setsmap.entrySet()) {
				int uid=entry.getKey();
				if(uids.contains(uid)){
					List<Integer> cardIds=entry.getValue();
					List<Card> hands=CardUtil.findCardsByCardId(deck,cardIds);
					PlayerData playerData=new PlayerData(uid,hands);
					pdkGameBase.getPlayers().put(uid,playerData);
					pdkGameBase.getHandsmap().put(uid, hands);//战绩使用
					deck.removeAll(hands);
					setcard_uids.add(uid);
				}
			}
			uids.removeAll(setcard_uids);
			for(int i=0;i<uids.size();i++) {
				int uid=uids.get(i);
				List<Card> hands=new ArrayList<>();
				hands.addAll(deck.subList(0, length));
				PlayerData playerData=new PlayerData(uid,hands);
				pdkGameBase.getPlayers().put(uid,playerData);
				pdkGameBase.getHandsmap().put(uid, hands);//战绩使用
				deck.removeAll(hands);
			}
			List<Card> dipai=new ArrayList<>();
			dipai.addAll(deck);
			pdkGameBase.getDipai().addAll(dipai);
			
			pdkRoomCache.setSetcardsPanel(new SetcardsPanel());//清除设置面板
		}else {
			
			//随机发牌
			if(pdkConfig.getPdk_mode()==PdkMode.MODE16) {
				deck.addAll(CardUtil.pdk16mode());
			}else if(pdkConfig.getPdk_mode()==PdkMode.MODE16CHOU4) {
				deck.addAll(CardUtil.pdk16modeChou4());
			}else if(pdkConfig.getPdk_mode()==PdkMode.MODE15) {
				deck.addAll(CardUtil.pdk15mode());
				length=15;
			}else {
				throw new RuntimeException("没有该种模式");
			}
			Collections.shuffle(deck);//洗牌
			for(int i=0;i<uids.size();i++) {
				int uid=uids.get(i);
				List<Card> hands=new ArrayList<>();
				hands.addAll(deck.subList(0,length));
				PlayerData playerData=new PlayerData(uid,hands);
				pdkGameBase.getPlayers().put(uid,playerData);
				pdkGameBase.getHandsmap().put(uid, hands);//战绩使用
				deck.removeAll(hands);
			}
			List<Card> dipai=new ArrayList<>();
			dipai.addAll(deck);
			pdkGameBase.getDipai().addAll(dipai);
		}
		
		boolean hashongshi=false;
		for(PlayerData playerData:pdkGameBase.getPlayers().values()) {
			List<Card> hands=new ArrayList<>();
			hands.addAll(playerData.getHands().values());
			hashongshi=RoomUtil.hong10InCardList(hands);
			if(hashongshi) {
				pdkGameBase.setHashongshi(true);
				break;
			}
		}
	}


	@Override
	public void reqDispatchCard(Room room, LogicController controller, List<Integer> cardIds) {
		int room_status=room.getRoom_status();
		if(room_status!=RoomStatus.GAMING) {
			controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_DISPATCHCARD, Resp.build(Code.GAME_NOT_BEGIN, "游戏还未开始")));
			return;
		}
		PdkGameBase pdkGameBase = (PdkGameBase) room.getGameBase();
		int dispatch_uid=pdkGameBase.getDispatch_uid();
		int uid=controller.getId();
		if(dispatch_uid!=uid) {
			controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_DISPATCHCARD, Resp.build(Code.NOT_TURN, "不该你操作")));
			return;
		}
		if(cardIds.isEmpty()) {
			RoomUtil.pass(room,controller);
			return;
		}
		RoomUtil.reqDispatchCard(room,controller,cardIds);
	}

	@Override
	public void reqHandCards(Room room, LogicController controller, int uid) {
		int role_id=controller.getRole_id();
		PdkGameBase pdkGameBase = (PdkGameBase) room.getGameBase();
		if(role_id==RoleId.SUPER_MANAGER) {
			PlayerData playerData =pdkGameBase.getPlayers().get(uid);
			if(playerData!=null) {
				ResPdkHandCards resPdkHandCards=PackageUtil.packageResPdkHandCards(playerData);
				controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_PDK_HANDCARDS,Resp.build(Code.OK, "获取手牌成功",resPdkHandCards)));
			}
		}
	}

	@Override
	public void reqSetcards(Room room, LogicController controller, List<Integer> cardIds) {
		PdkConfig pdkConfig = (PdkConfig) room.getGameConfig();
		int pdk_mode=pdkConfig.getPdk_mode();
		PdkRoomCache pdkRoomCache = (PdkRoomCache) room.getRoomCache();
		SetcardsPanel setcardsPanel = pdkRoomCache.getSetcardsPanel();
		Map<Integer,List<Integer>> setsmap=setcardsPanel.getSetsmap();
		if(pdk_mode==PdkMode.MODE15) {
			if(cardIds.size()!=15) {
				//15张
				controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_SETCARDS, Resp.build(Code.PARAM_ERROR, "必须15张")));
				return;
			}
			List<Card> list=CardUtil.pdk15mode();
			List<Integer> allcardIds=new ArrayList<>();
			for(Card card:list) {
				allcardIds.add(card.getCardId());
			}
			boolean allhas=allcardIds.containsAll(cardIds);
			if(!allhas) {
				controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_SETCARDS, Resp.build(Code.PARAM_ERROR, "存在找不到的牌id")));
				return;
			}
			boolean repeated=false;
			for(List<Integer> tmp:setsmap.values()) {
				for(Integer cardId:cardIds) {
					if(tmp.contains(cardId)) {
						//重复了
						repeated=true;
						break;
					}
				}
				if(repeated) {
					break;
				}
			}
			
			if(repeated) {
				//牌设置重复了,返回最新的牌组给客户端
				for(List<Integer> tmp:setsmap.values()) {
					allcardIds.removeAll(tmp);
				}
				controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_SETCARDS, Resp.build(Code.PARAM_ERROR, "剩余牌错误",PackageUtil.packageResSetcards(allcardIds))));
				return;
			}
			
			setsmap.put(controller.getId(), cardIds);
			controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_SETCARDS, Resp.build(Code.OK, "设置牌成功,下局生效")));
		}else if(pdk_mode==PdkMode.MODE16) {
			if(cardIds.size()!=16) {
				controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_SETCARDS, Resp.build(Code.PARAM_ERROR, "必须16张")));
				return;
			}
			List<Card> list=CardUtil.pdk16mode();
			List<Integer> allcardIds=new ArrayList<>();
			for(Card card:list) {
				allcardIds.add(card.getCardId());
			}
			boolean allhas=allcardIds.containsAll(cardIds);
			if(!allhas) {
				controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_SETCARDS, Resp.build(Code.PARAM_ERROR, "存在找不到的牌id")));
				return;
			}
			boolean repeated=false;
			for(List<Integer> tmp:setsmap.values()) {
				for(Integer cardId:cardIds) {
					if(tmp.contains(cardId)) {
						//重复了
						repeated=true;
						break;
					}
				}
				if(repeated) {
					break;
				}
			}
			
			if(repeated) {
				//牌设置重复了,返回最新的牌组给客户端
				for(List<Integer> tmp:setsmap.values()) {
					allcardIds.removeAll(tmp);
				}
				controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_SETCARDS, Resp.build(Code.PARAM_ERROR, "剩余牌错误",PackageUtil.packageResSetcards(allcardIds))));
				return;
			}
			
			setsmap.put(controller.getId(), cardIds);
			controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_SETCARDS, Resp.build(Code.OK, "设置牌成功,下局生效")));
		}else {
			controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_SETCARDS, Resp.build(Code.PARAM_ERROR, "不支持该模式配牌")));
		}
		
	}

	@Override
	public void reqSetcardsLeft(Room room, LogicController controller) {
		PdkConfig pdkConfig = (PdkConfig) room.getGameConfig();
		int pdk_mode=pdkConfig.getPdk_mode();
		PdkRoomCache pdkRoomCache = (PdkRoomCache) room.getRoomCache();
		SetcardsPanel setcardsPanel = pdkRoomCache.getSetcardsPanel();
		Map<Integer,List<Integer>> setsmap=setcardsPanel.getSetsmap();
		List<Integer> list=new ArrayList<>();
		for(List<Integer> tmp:setsmap.values()) {
			list.addAll(tmp);
		}
		if(pdk_mode==PdkMode.MODE15) {
			List<Card> cards=CardUtil.pdk15mode();
			List<Integer> all=new ArrayList<>();
			for(Card card:cards) {
				all.add(card.getCardId());
			}
			all.removeAll(list);
			controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_SETCARDS_LEFT, Resp.build(Code.OK, "拉取余下的牌成功",PackageUtil.packageResSetcardsLeft(all))));
		}else if(pdk_mode==PdkMode.MODE16) {
			List<Card> cards=CardUtil.pdk16mode();
			List<Integer> all=new ArrayList<>();
			for(Card card:cards) {
				all.add(card.getCardId());
			}
			all.removeAll(list);
			controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_SETCARDS_LEFT, Resp.build(Code.OK, "拉取余下的牌成功",PackageUtil.packageResSetcardsLeft(all))));
		}else {
			controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_SETCARDS_LEFT, Resp.build(Code.PARAM_ERROR, "不支持该模式配牌")));
		}
	}

	@Override
	public void reqShootBird(Room room, LogicController controller, int bird) {
		if(bird<0) {
			return;
		}
		int room_times=room.getRoom_times();
		if(room_times!=0) {
			//当前不能打鸟
			return;
		}
		PdkConfig pdkConfig=(PdkConfig) room.getGameConfig();
		if(pdkConfig.getBird()==0) {
			//不允许打鸟
			return;
		}
		PdkRoomCache pdkRoomCache = (PdkRoomCache) room.getRoomCache();
		if(pdkRoomCache.getBirds().containsKey(controller.getId())) {
			//玩家已经打过鸟了
			return;
		}
		if(bird>pdkConfig.getBird_max()) {
			//最大打30倍
			return;
		}
		pdkRoomCache.getBirds().put(controller.getId(), bird);
		controller.getWebClient().sendMessage(Message.build(PDKCMD.RES_SHOOT_BIRD, Resp.build(Code.OK, "打鸟成功")));
	}
}
